// Copyright 2021 Code Intelligence GmbH
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package com.code_intelligence.jazzer.autofuzz;

import java.io.Closeable;
import java.io.IOException;
import java.io.Serializable;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.Objects;

// Returned by Meta when asked to construct a Class object. Its purpose is to be a relatively
// "interesting" Java data class that can serve as the target of methods that perform some kind of
// reflection or deserialization.
public class YourAverageJavaClass implements Cloneable, Closeable, Serializable {
  public byte aByte;
  public boolean aBoolean;
  public double aDouble;
  public float aFloat;
  public int anInt;
  public transient int transientInt;
  public long aLong;
  public short aShort;
  public volatile short volatileShort;
  public String string;
  public byte[] bytes;
  public List<YourAverageJavaClass> list;
  public Map<String, YourAverageJavaClass> map;

  // Everything below has been automatically generated (apart from a minor modification to clone());

  public YourAverageJavaClass(
      byte aByte,
      boolean aBoolean,
      double aDouble,
      float aFloat,
      int anInt,
      int transientInt,
      long aLong,
      short aShort,
      short volatileShort,
      String string) {
    this.aByte = aByte;
    this.aBoolean = aBoolean;
    this.aDouble = aDouble;
    this.aFloat = aFloat;
    this.anInt = anInt;
    this.transientInt = transientInt;
    this.aLong = aLong;
    this.aShort = aShort;
    this.volatileShort = volatileShort;
    this.string = string;
  }

  public YourAverageJavaClass() {}

  public YourAverageJavaClass(
      byte aByte,
      boolean aBoolean,
      double aDouble,
      float aFloat,
      int anInt,
      int transientInt,
      long aLong,
      short aShort,
      short volatileShort,
      String string,
      byte[] bytes,
      List<YourAverageJavaClass> list,
      Map<String, YourAverageJavaClass> map) {
    this.aByte = aByte;
    this.aBoolean = aBoolean;
    this.aDouble = aDouble;
    this.aFloat = aFloat;
    this.anInt = anInt;
    this.transientInt = transientInt;
    this.aLong = aLong;
    this.aShort = aShort;
    this.volatileShort = volatileShort;
    this.string = string;
    this.bytes = bytes;
    this.list = list;
    this.map = map;
  }

  public byte getaByte() {
    return aByte;
  }

  public void setaByte(byte aByte) {
    this.aByte = aByte;
  }

  public boolean isaBoolean() {
    return aBoolean;
  }

  public void setaBoolean(boolean aBoolean) {
    this.aBoolean = aBoolean;
  }

  public double getaDouble() {
    return aDouble;
  }

  public void setaDouble(double aDouble) {
    this.aDouble = aDouble;
  }

  public float getaFloat() {
    return aFloat;
  }

  public void setaFloat(float aFloat) {
    this.aFloat = aFloat;
  }

  public int getAnInt() {
    return anInt;
  }

  public void setAnInt(int anInt) {
    this.anInt = anInt;
  }

  public int getTransientInt() {
    return transientInt;
  }

  public void setTransientInt(int transientInt) {
    this.transientInt = transientInt;
  }

  public long getaLong() {
    return aLong;
  }

  public void setaLong(long aLong) {
    this.aLong = aLong;
  }

  public short getaShort() {
    return aShort;
  }

  public void setaShort(short aShort) {
    this.aShort = aShort;
  }

  public short getVolatileShort() {
    return volatileShort;
  }

  public void setVolatileShort(short volatileShort) {
    this.volatileShort = volatileShort;
  }

  public String getString() {
    return string;
  }

  public void setString(String string) {
    this.string = string;
  }

  public byte[] getBytes() {
    return bytes;
  }

  public void setBytes(byte[] bytes) {
    this.bytes = bytes;
  }

  public List<YourAverageJavaClass> getList() {
    return list;
  }

  public void setList(List<YourAverageJavaClass> list) {
    this.list = list;
  }

  public Map<String, YourAverageJavaClass> getMap() {
    return map;
  }

  public void setMap(Map<String, YourAverageJavaClass> map) {
    this.map = map;
  }

  @Override
  public YourAverageJavaClass clone() {
    try {
      YourAverageJavaClass clone = (YourAverageJavaClass) super.clone();
      clone.transientInt = transientInt + 1;
      clone.volatileShort = (short) (volatileShort - 1);
      return clone;
    } catch (CloneNotSupportedException e) {
      throw new AssertionError();
    }
  }

  @Override
  public boolean equals(Object o) {
    if (this == o) return true;
    if (!(o instanceof YourAverageJavaClass)) return false;
    YourAverageJavaClass that = (YourAverageJavaClass) o;
    return aByte == that.aByte
        && aBoolean == that.aBoolean
        && Double.compare(that.aDouble, aDouble) == 0
        && Float.compare(that.aFloat, aFloat) == 0
        && anInt == that.anInt
        && transientInt == that.transientInt
        && aLong == that.aLong
        && aShort == that.aShort
        && volatileShort == that.volatileShort
        && Objects.equals(string, that.string)
        && Arrays.equals(bytes, that.bytes)
        && Objects.equals(list, that.list)
        && Objects.equals(map, that.map);
  }

  @Override
  public int hashCode() {
    int result =
        Objects.hash(
            aByte,
            aBoolean,
            aDouble,
            aFloat,
            anInt,
            transientInt,
            aLong,
            aShort,
            volatileShort,
            string,
            list,
            map);
    result = 31 * result + Arrays.hashCode(bytes);
    return result;
  }

  @Override
  public String toString() {
    return "YourAverageJavaClass{"
        + "aByte="
        + aByte
        + ", aBoolean="
        + aBoolean
        + ", aDouble="
        + aDouble
        + ", aFloat="
        + aFloat
        + ", anInt="
        + anInt
        + ", transientInt="
        + transientInt
        + ", aLong="
        + aLong
        + ", aShort="
        + aShort
        + ", volatileShort="
        + volatileShort
        + ", string='"
        + string
        + '\''
        + ", bytes="
        + Arrays.toString(bytes)
        + ", list="
        + list
        + ", map="
        + map
        + '}';
  }

  @Override
  public void close() throws IOException {}
}
